PostMessage API का उपयोग करके सुरक्षित क्रॉस-ओरिजिन कम्युनिकेशन का अन्वेषण करें। वेब अनुप्रयोगों में कमजोरियों को कम करने के लिए इसकी क्षमताओं, सुरक्षा जोखिमों और सर्वोत्तम प्रथाओं के बारे में जानें।
क्रॉस-ओरिजिन कम्युनिकेशन: PostMessage API के साथ सुरक्षा पैटर्न
आधुनिक वेब में, अनुप्रयोगों को अक्सर विभिन्न ओरिजिन से संसाधनों के साथ इंटरैक्ट करने की आवश्यकता होती है। सेम-ओरिजिन पॉलिसी (SOP) एक महत्वपूर्ण सुरक्षा तंत्र है जो स्क्रिप्ट को एक अलग ओरिजिन से संसाधनों तक पहुंचने से रोकता है। हालांकि, कुछ वैध परिदृश्य हैं जहां क्रॉस-ओरिजिन कम्युनिकेशन आवश्यक है। postMessage API इसे प्राप्त करने के लिए एक नियंत्रित तंत्र प्रदान करता है, लेकिन इसके संभावित सुरक्षा जोखिमों को समझना और उचित सुरक्षा पैटर्न लागू करना महत्वपूर्ण है।
सेम-ओरिजिन पॉलिसी (SOP) को समझना
सेम-ओरिजिन पॉलिसी वेब ब्राउज़रों में एक मौलिक सुरक्षा अवधारणा है। यह वेब पेजों को उस डोमेन से अलग डोमेन पर अनुरोध करने से रोकता है जिसने वेब पेज परोसा है। एक ओरिजिन को स्कीम (प्रोटोकॉल), होस्ट (डोमेन) और पोर्ट द्वारा परिभाषित किया जाता है। यदि इनमें से कोई भी भिन्न होता है, तो ओरिजिन को अलग माना जाता है। उदाहरण के लिए:
https://example.comhttps://www.example.comhttp://example.comhttps://example.com:8080
ये सभी अलग-अलग ओरिजिन हैं, और SOP इनके बीच सीधी स्क्रिप्ट पहुंच को प्रतिबंधित करता है।
PostMessage API का परिचय
postMessage API क्रॉस-ओरिजिन कम्युनिकेशन के लिए एक सुरक्षित और नियंत्रित तंत्र प्रदान करता है। यह स्क्रिप्ट को उनके ओरिजिन की परवाह किए बिना, अन्य विंडो (जैसे, iframe, नई विंडो, या टैब) को संदेश भेजने की अनुमति देता है। प्राप्त करने वाली विंडो फिर इन संदेशों को सुन सकती है और तदनुसार उन्हें संसाधित कर सकती है।
संदेश भेजने के लिए मूल सिंटैक्स है:
otherWindow.postMessage(message, targetOrigin);
otherWindow: लक्ष्य विंडो का एक संदर्भ (जैसे,window.parent,iframe.contentWindow, याwindow.openसे प्राप्त एक विंडो ऑब्जेक्ट)।message: वह डेटा जिसे आप भेजना चाहते हैं। यह कोई भी जावास्क्रिप्ट ऑब्जेक्ट हो सकता है जिसे सीरियलाइज किया जा सकता है (जैसे, स्ट्रिंग्स, नंबर, ऑब्जेक्ट्स, एरे)।targetOrigin: उस ओरिजिन को निर्दिष्ट करता है जिस पर आप संदेश भेजना चाहते हैं। यह एक महत्वपूर्ण सुरक्षा पैरामीटर है।
प्राप्त करने वाले छोर पर, आपको message ईवेंट के लिए सुनना होगा:
window.addEventListener('message', function(event) {
// ...
});
event ऑब्जेक्ट में निम्नलिखित गुण होते हैं:
event.data: दूसरी विंडो द्वारा भेजा गया संदेश।event.origin: संदेश भेजने वाली विंडो का ओरिजिन।event.source: संदेश भेजने वाली विंडो का एक संदर्भ।
सुरक्षा जोखिम और कमजोरियाँ
हालांकि postMessage SOP प्रतिबंधों को बायपास करने का एक तरीका प्रदान करता है, अगर इसे सावधानी से लागू नहीं किया जाता है तो यह संभावित सुरक्षा जोखिम भी प्रस्तुत करता है। यहां कुछ सामान्य कमजोरियां हैं:
1. टारगेट ओरिजिन का बेमेल होना
event.origin प्रॉपर्टी को मान्य करने में विफल होना एक महत्वपूर्ण भेद्यता है। यदि रिसीवर आँख मूंदकर संदेश पर भरोसा करता है, तो कोई भी वेबसाइट दुर्भावनापूर्ण डेटा भेज सकती है। संदेश को संसाधित करने से पहले हमेशा सत्यापित करें कि event.origin अपेक्षित ओरिजिन से मेल खाता है।
उदाहरण (असुरक्षित कोड):
window.addEventListener('message', function(event) {
// यह न करें!
processMessage(event.data);
});
उदाहरण (सुरक्षित कोड):
window.addEventListener('message', function(event) {
if (event.origin !== 'https://trusted-origin.com') {
console.warn('अविश्वसनीय ओरिजिन से संदेश प्राप्त हुआ:', event.origin);
return;
}
processMessage(event.data);
});
2. डेटा इंजेक्शन
प्राप्त डेटा (event.data) को निष्पादन योग्य कोड के रूप में मानना या सीधे DOM में इंजेक्ट करना क्रॉस-साइट स्क्रिप्टिंग (XSS) कमजोरियों को जन्म दे सकता है। इसका उपयोग करने से पहले हमेशा प्राप्त डेटा को सैनिटाइज और मान्य करें।
उदाहरण (असुरक्षित कोड):
window.addEventListener('message', function(event) {
if (event.origin === 'https://trusted-origin.com') {
document.body.innerHTML = event.data; // यह न करें!
}
});
उदाहरण (सुरक्षित कोड):
window.addEventListener('message', function(event) {
if (event.origin === 'https://trusted-origin.com') {
const sanitizedData = sanitize(event.data); // एक उचित सैनिटाइजेशन फ़ंक्शन लागू करें
document.getElementById('message-container').textContent = sanitizedData;
}
});
function sanitize(data) {
// यहां मजबूत सैनिटाइजेशन तर्क लागू करें।
// उदाहरण के लिए, DOMPurify या एक समान लाइब्रेरी का उपयोग करें
return DOMPurify.sanitize(data);
}
3. मैन-इन-द-मिडल (MITM) हमले
यदि संचार एक असुरक्षित चैनल (HTTP) पर होता है, तो एक MITM हमलावर संदेशों को रोक सकता है और संशोधित कर सकता है। सुरक्षित संचार के लिए हमेशा HTTPS का उपयोग करें।
4. क्रॉस-साइट रिक्वेस्ट फोर्जरी (CSRF)
यदि रिसीवर उचित सत्यापन के बिना प्राप्त संदेश के आधार पर कार्य करता है, तो एक हमलावर संभावित रूप से रिसीवर को अनपेक्षित कार्यों को करने के लिए धोखा देने के लिए संदेशों को गढ़ सकता है। CSRF सुरक्षा तंत्र लागू करें, जैसे संदेश में एक गुप्त टोकन शामिल करना और इसे रिसीवर पक्ष पर सत्यापित करना।
5. targetOrigin में वाइल्डकार्ड का उपयोग करना
targetOrigin को * पर सेट करना किसी भी ओरिजिन को संदेश प्राप्त करने की अनुमति देता है। इससे तब तक बचा जाना चाहिए जब तक कि यह बिल्कुल आवश्यक न हो, क्योंकि यह ओरिजिन-आधारित सुरक्षा के उद्देश्य को विफल करता है। यदि आपको * का उपयोग करना ही है, तो सुनिश्चित करें कि आप अन्य मजबूत सुरक्षा उपाय लागू करते हैं, जैसे संदेश प्रमाणीकरण कोड (MACs)।
उदाहरण (इससे बचें):
otherWindow.postMessage(message, '*'); // '*' का उपयोग तब तक न करें जब तक बिल्कुल आवश्यक न हो
सुरक्षा पैटर्न और सर्वोत्तम प्रथाएं
postMessage से जुड़े जोखिमों को कम करने के लिए, इन सुरक्षा पैटर्न और सर्वोत्तम प्रथाओं का पालन करें:
1. सख्त ओरिजिन सत्यापन
रिसीवर पक्ष पर हमेशा event.origin प्रॉपर्टी को मान्य करें। इसे विश्वसनीय ओरिजिन की पूर्वनिर्धारित सूची से तुलना करें। तुलना के लिए सख्त समानता (===) का उपयोग करें।
2. डेटा सैनिटाइजेशन और सत्यापन
postMessage के माध्यम से प्राप्त सभी डेटा को उपयोग करने से पहले सैनिटाइज और मान्य करें। डेटा का उपयोग कैसे किया जाएगा, इसके आधार पर उपयुक्त सैनिटाइजेशन तकनीकों का उपयोग करें (जैसे, HTML एस्केपिंग, URL एन्कोडिंग, इनपुट वैलिडेशन)। HTML को सैनिटाइज करने के लिए DOMPurify जैसी लाइब्रेरी का उपयोग करें।
3. संदेश प्रमाणीकरण कोड (MACs)
संदेश की अखंडता और प्रामाणिकता सुनिश्चित करने के लिए संदेश में एक संदेश प्रमाणीकरण कोड (MAC) शामिल करें। प्रेषक एक साझा गुप्त कुंजी का उपयोग करके MAC की गणना करता है और इसे संदेश में शामिल करता है। रिसीवर उसी साझा गुप्त कुंजी का उपयोग करके MAC की पुनर्गणना करता है और प्राप्त MAC से इसकी तुलना करता है। यदि वे मेल खाते हैं, तो संदेश को प्रामाणिक और बिना छेड़छाड़ वाला माना जाता है।
उदाहरण (HMAC-SHA256 का उपयोग करके):
// प्रेषक
async function sendMessage(message, targetOrigin, sharedSecret) {
const encoder = new TextEncoder();
const data = encoder.encode(JSON.stringify(message));
const key = await crypto.subtle.importKey(
"raw",
encoder.encode(sharedSecret),
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"]
);
const signature = await crypto.subtle.sign("HMAC", key, data);
const signatureArray = Array.from(new Uint8Array(signature));
const signatureHex = signatureArray.map(b => b.toString(16).padStart(2, '0')).join('');
const securedMessage = {
data: message,
signature: signatureHex
};
otherWindow.postMessage(securedMessage, targetOrigin);
}
// रिसीवर
async function receiveMessage(event, sharedSecret) {
if (event.origin !== 'https://trusted-origin.com') {
console.warn('अविश्वसनीय ओरिजिन से संदेश प्राप्त हुआ:', event.origin);
return;
}
const securedMessage = event.data;
const message = securedMessage.data;
const receivedSignature = securedMessage.signature;
const encoder = new TextEncoder();
const data = encoder.encode(JSON.stringify(message));
const key = await crypto.subtle.importKey(
"raw",
encoder.encode(sharedSecret),
{ name: "HMAC", hash: "SHA-256" },
false,
["verify"]
);
const signature = await crypto.subtle.sign("HMAC", key, data);
const signatureArray = Array.from(new Uint8Array(signature));
const signatureHex = signatureArray.map(b => b.toString(16).padStart(2, '0')).join('');
if (signatureHex === receivedSignature) {
console.log('संदेश प्रामाणिक है!');
processMessage(message); // संदेश को संसाधित करने के लिए आगे बढ़ें
} else {
console.error('संदेश हस्ताक्षर सत्यापन विफल!');
}
}
महत्वपूर्ण: साझा गुप्त कुंजी को सुरक्षित रूप से उत्पन्न और संग्रहीत किया जाना चाहिए। कोड में कुंजी को हार्डकोड करने से बचें।
4. नॉन्स और टाइमस्टैम्प का उपयोग
रीप्ले हमलों को रोकने के लिए, संदेश में एक अद्वितीय नॉन्स (एक बार उपयोग की जाने वाली संख्या) और एक टाइमस्टैम्प शामिल करें। रिसीवर तब यह सत्यापित कर सकता है कि नॉन्स का उपयोग पहले नहीं किया गया है और टाइमस्टैम्प एक स्वीकार्य समय-सीमा के भीतर है। यह एक हमलावर द्वारा पहले से इंटरसेप्ट किए गए संदेशों को फिर से चलाने के जोखिम को कम करता है।
5. न्यूनतम विशेषाधिकार का सिद्धांत
दूसरी विंडो को केवल न्यूनतम आवश्यक विशेषाधिकार दें। उदाहरण के लिए, यदि दूसरी विंडो को केवल डेटा पढ़ने की आवश्यकता है, तो उसे डेटा लिखने की अनुमति न दें। अपने संचार प्रोटोकॉल को न्यूनतम विशेषाधिकार के सिद्धांत को ध्यान में रखकर डिज़ाइन करें।
6. सामग्री सुरक्षा नीति (CSP)
सामग्री सुरक्षा नीति (CSP) का उपयोग उन स्रोतों को प्रतिबंधित करने के लिए करें जिनसे स्क्रिप्ट लोड की जा सकती हैं और वे कार्य जो स्क्रिप्ट कर सकती हैं। यह उन XSS कमजोरियों के प्रभाव को कम करने में मदद कर सकता है जो postMessage डेटा के अनुचित संचालन से उत्पन्न हो सकती हैं।
7. इनपुट सत्यापन
प्राप्त डेटा की संरचना और प्रारूप को हमेशा मान्य करें। एक स्पष्ट संदेश प्रारूप परिभाषित करें और सुनिश्चित करें कि प्राप्त डेटा इस प्रारूप के अनुरूप है। यह अप्रत्याशित व्यवहार और कमजोरियों को रोकने में मदद करता है।
8. सुरक्षित डेटा सीरियलाइजेशन
संदेशों को सीरियलाइज और डीसीरियलाइज करने के लिए एक सुरक्षित डेटा सीरियलाइजेशन प्रारूप, जैसे JSON, का उपयोग करें। ऐसे प्रारूपों का उपयोग करने से बचें जो कोड निष्पादन की अनुमति देते हैं, जैसे eval() या Function()।
9. संदेश आकार सीमित करें
postMessage के माध्यम से भेजे गए संदेशों के आकार को सीमित करें। बड़े संदेश अत्यधिक संसाधनों की खपत कर सकते हैं और संभावित रूप से सेवा-से-इनकार (denial-of-service) हमलों का कारण बन सकते हैं।
10. नियमित सुरक्षा ऑडिट
संभावित कमजोरियों की पहचान करने और उन्हें दूर करने के लिए अपने कोड का नियमित सुरक्षा ऑडिट करें। postMessage के कार्यान्वयन पर पूरा ध्यान दें और सुनिश्चित करें कि सभी सुरक्षा सर्वोत्तम प्रथाओं का पालन किया जाता है।
उदाहरण परिदृश्य: एक Iframe और उसके Parent के बीच सुरक्षित संचार
एक ऐसे परिदृश्य पर विचार करें जहां https://iframe.example.com पर होस्ट किए गए एक iframe को https://parent.example.com पर होस्ट किए गए अपने पैरेंट पेज के साथ संवाद करने की आवश्यकता है। iframe को प्रोसेसिंग के लिए पैरेंट पेज पर उपयोगकर्ता डेटा भेजने की आवश्यकता है।
Iframe (https://iframe.example.com):
// एक साझा गुप्त कुंजी उत्पन्न करें (इसे एक सुरक्षित कुंजी उत्पादन विधि से बदलें)
const sharedSecret = 'YOUR_SECURE_SHARED_SECRET';
// उपयोगकर्ता डेटा प्राप्त करें
const userData = {
name: 'John Doe',
email: 'john.doe@example.com'
};
// उपयोगकर्ता डेटा को पैरेंट पेज पर भेजें
async function sendUserData(userData) {
const encoder = new TextEncoder();
const data = encoder.encode(JSON.stringify(userData));
const key = await crypto.subtle.importKey(
"raw",
encoder.encode(sharedSecret),
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"]
);
const signature = await crypto.subtle.sign("HMAC", key, data);
const signatureArray = Array.from(new Uint8Array(signature));
const signatureHex = signatureArray.map(b => b.toString(16).padStart(2, '0')).join('');
const securedMessage = {
data: userData,
signature: signatureHex
};
parent.postMessage(securedMessage, 'https://parent.example.com');
}
sendUserData(userData);
Parent Page (https://parent.example.com):
// साझा गुप्त कुंजी (iframe की कुंजी से मेल खाना चाहिए)
const sharedSecret = 'YOUR_SECURE_SHARED_SECRET';
window.addEventListener('message', async function(event) {
if (event.origin !== 'https://iframe.example.com') {
console.warn('अविश्वसनीय ओरिजिन से संदेश प्राप्त हुआ:', event.origin);
return;
}
const securedMessage = event.data;
const userData = securedMessage.data;
const receivedSignature = securedMessage.signature;
const encoder = new TextEncoder();
const data = encoder.encode(JSON.stringify(userData));
const key = await crypto.subtle.importKey(
"raw",
encoder.encode(sharedSecret),
{ name: "HMAC", hash: "SHA-256" },
false,
["verify"]
);
const signature = await crypto.subtle.sign("HMAC", key, data);
const signatureArray = Array.from(new Uint8Array(signature));
const signatureHex = signatureArray.map(b => b.toString(16).padStart(2, '0')).join('');
if (signatureHex === receivedSignature) {
console.log('संदेश प्रामाणिक है!');
// उपयोगकर्ता डेटा को संसाधित करें
console.log('उपयोगकर्ता डेटा:', userData);
} else {
console.error('संदेश हस्ताक्षर सत्यापन विफल!');
}
});
महत्वपूर्ण नोट्स:
YOUR_SECURE_SHARED_SECRETको एक सुरक्षित रूप से उत्पन्न साझा गुप्त कुंजी से बदलें।- साझा गुप्त कुंजी iframe और पैरेंट पेज दोनों में समान होनी चाहिए।
- यह उदाहरण संदेश प्रमाणीकरण के लिए HMAC-SHA256 का उपयोग करता है।
निष्कर्ष
postMessage API वेब अनुप्रयोगों में क्रॉस-ओरिजिन कम्युनिकेशन को सक्षम करने के लिए एक शक्तिशाली उपकरण है। हालांकि, संभावित सुरक्षा जोखिमों को समझना और इन जोखिमों को कम करने के लिए उपयुक्त सुरक्षा पैटर्न लागू करना महत्वपूर्ण है। इस गाइड में उल्लिखित सुरक्षा पैटर्न और सर्वोत्तम प्रथाओं का पालन करके, आप मजबूत और सुरक्षित वेब एप्लिकेशन बनाने के लिए postMessage का सुरक्षित रूप से उपयोग कर सकते हैं।
हमेशा सुरक्षा को प्राथमिकता देना याद रखें और वेब विकास के लिए नवीनतम सुरक्षा सर्वोत्तम प्रथाओं के साथ अद्यतित रहें। यह सुनिश्चित करने के लिए कि आपके एप्लिकेशन संभावित कमजोरियों से सुरक्षित हैं, अपने कोड और सुरक्षा कॉन्फ़िगरेशन की नियमित रूप से समीक्षा करें।